<template>
  <div>
    <n-card :content-style="{paddingBottom: '0px',paddingTop: '17px'}">
      <n-space>
        <n-form label-placement="left">
          <n-form-item label="类别 :" size="small">
            <n-tag v-for="tag in characterTags" v-model:checked="tag.checked" checkable @click="getCharacterInfoList"
                   style="margin-left: 1px;">
              {{ tag.label }}
            </n-tag>
          </n-form-item>
          <n-grid :x-gap="30">
            <n-grid-item :span="8">
              <n-form-item label="引擎 :" size="small">
                <n-tag v-for="tag in paintEngine" v-model:checked="tag.checked" checkable @click="getCharacterInfoList"
                       style="margin-left: 1px;">
                  {{ tag.label }}
                </n-tag>
              </n-form-item>
            </n-grid-item>
<!--            <n-grid-item :span="8">-->
<!--              <n-form-item label="名称 :" size="small">-->
<!--                <n-input v-model:value="queryForm.name" placeholder="请输入模特名称"></n-input>-->
<!--              </n-form-item>-->
<!--            </n-grid-item>-->

<!--            <n-grid-item :span="8">-->
<!--              <n-form-item label="资源类型 :" size="small">-->
<!--                <n-select :options="typeOptions" v-model:value="queryForm.isOnline"></n-select>-->
<!--              </n-form-item>-->
<!--            </n-grid-item>-->
          </n-grid>
        </n-form>
      </n-space>
    </n-card>
    <n-card style="margin-top: 5px">
      <n-space justify="space-between">
        <n-button type="primary" style="margin-bottom: 10px;"
                  @click="resetForm() ;formTitle = '新增人物信息'; addModalShow = true">
          <template #icon>
            <n-icon>
              <AddSharp/>
            </n-icon>
          </template>
          新增
        </n-button>
        <n-button type="info" @click="syncData" :loading="syncLoading">
          同步云端人物
        </n-button>
      </n-space>
      <n-scrollbar
          :content-style="{padding: '5px 5px 5px 5px', height: clientHeight - (layoutHeaderHeight  + tabsHeight + 262) + 'px'}">
        <n-grid x-gap="4" y-gap="10" :cols="5" item-responsive responsive="screen">
          <n-gi v-for="characterInfo in characterInfoList">
            <n-card :title="characterInfo.characterName" content-style="padding: 5px 5px 5px 5px;">
              <template #header-extra>
                {{ characterInfo.characterGender }}
                <n-divider vertical/>
                {{ characterInfo.characterAge }}
              </template>
              <template #cover>
                <n-space justify="center">
                  <n-image height="300" style="max-height:  300px" :object-fit="'cover'"
                           v-if="characterInfo.characterAvatar"
                           :src="fileFunction.getCharacterInfoImage(characterInfo?.characterAvatar)">
                  </n-image>
                </n-space>
              </template>

              <n-ellipsis v-if="characterInfo.characterNickname">
                别名 : {{ characterInfo.characterNickname }}
              </n-ellipsis>
              <n-ellipsis v-if="!characterInfo.characterNickname">
                别名 : 暂无
              </n-ellipsis>
              <n-ellipsis>
                描述 : {{ characterInfo.characterDescription }}
              </n-ellipsis>
              <n-space style="margin-top: 5px;">
                <n-tag type="primary" style="padding-left: 2px;padding-right:2px">
                  {{ characterInfo.engineType }}
                </n-tag>
                <n-tag type="warning"
                       v-if="characterInfo.engineType=='MJ' && ( characterInfo.remoteUrl==null || characterInfo.remoteUrl==='')">
                  未填写外网链接
                </n-tag>

                <n-tag type="primary"
                       v-if="characterInfo.engineType=='MJ' && ( characterInfo.remoteUrl!= null &&  characterInfo.remoteUrl.length>0)">
                  <n-a target="_blank"
                       :href="characterInfo.ccRemoteUrl">
                    外网链接
                  </n-a>
                </n-tag>

                <n-tag v-if="characterInfo.isOnline" type="error">
                  云端资源
                </n-tag>

                <n-button :loading="uploadDiscordLoading" secondary type="primary"
                          @click="uploadToDiscord(characterInfo.id)" size="small"
                          v-if="!client" >
                  上传图床
                </n-button>

              </n-space>
              <template #action>
                <n-space justify="end" v-if="props.mode === 'choseCharacterInfo'">
                  <n-button size="small" type="primary" @click="props.choseCharacter(characterInfo)">选择</n-button>
                </n-space>
                <n-space justify="end" v-else>
                  <n-space>
                    <n-button size="small" type="info" :loading="deleteLoading"
                              @click="editForm(characterInfo)">修改
                    </n-button>
                    <n-button size="small" type="error" :loading="deleteLoading"
                              @click="deleteCharacterInfo(characterInfo)">删除
                    </n-button>
                  </n-space>
                </n-space>
              </template>
            </n-card>
          </n-gi>
        </n-grid>
      </n-scrollbar>
      <n-space justify="end" style="margin-top: 10px">
        <n-pagination
          :display-order="['quick-jumper', 'pages', 'size-picker']"
          :item-count="tableTotal"
          :page-size="paginationReactive.pageSize"
          :page-sizes="paginationReactive.pageSizes"
          show-quick-jumper
          show-size-picker
          :on-update:page-size="onPageSizeChange"
          :on-update:page="onPageChange"
        />
      </n-space>
    </n-card>

    <n-drawer v-model:show="addModalShow" :width="800" :on-after-leave="getCharacterInfoList">
      <n-drawer-content :title="formTitle">
        <n-form
            ref="formRef"
            label-placement="left"
            :label-width="80"
            :rules="rules"
            :model="characterForm"
        >
          <n-grid :cols="24">
            <n-form-item-gi :span="24" label="名称" path="characterName">
              <n-input v-model:value="characterForm.characterName" placeholder="人物名称"/>
            </n-form-item-gi>

            <n-form-item-gi :span="24" label="别名" path="characterNicknames">
              <n-dynamic-tags v-model:value="characterForm.characterNicknames"/>
            </n-form-item-gi>

            <n-form-item-gi :span="24" label="引擎" path="engineType">
              <n-select :options="paintEngine" v-model:value="characterForm.engineType"></n-select>
            </n-form-item-gi>

            <n-form-item-gi :span="12" label="性别" path="characterGender">
              <n-select :options="sexDict" v-model:value="characterForm.characterGender" @update:value="sexSelect">
              </n-select>
            </n-form-item-gi>

            <n-form-item-gi :span="12" label="年龄段" path="characterAge">
              <n-select :options="ageTypeOptions" v-model:value="characterForm.characterAge" @update:value="ageSelect"
                        clearable></n-select>
            </n-form-item-gi>

            <n-form-item-gi :span="24" label="人物描述" path="characterDescription">
              <n-input
                  v-model:value="characterForm.characterDescription"
                  type="textarea" style="height: 100px;"
                  placeholder="人物性别,形象,衣着描述">
              </n-input>

              <n-button type="primary" style="height: 100px; margin-left: 5px;" @click="promptTemplateShow = true">
                提示词器
              </n-button>
            </n-form-item-gi>

            <n-form-item-gi :span="24" label=" " path="characterAvatar">
              <n-card title="人物照片">
                <template #header-extra>
                  <n-space justify="end" v-if="characterForm.characterAvatar">
                    <n-button size="small" type="primary" @click="interrogateImage" :loading="interrogateLoading">
                      反推关键词
                    </n-button>
                    <n-button size="small" type="warning" @click="characterForm.characterAvatar = ''">清除</n-button>
                  </n-space>
                </template>
                <n-space justify="center">
                  <n-image
                      :style="{
                        width: canvasWidth + 'px',
                        height: canvasHeight + 'px'
                        }"
                      v-if="characterForm.characterAvatar && characterForm.characterAvatar.startsWith('data:image')"
                      :src="characterForm.characterAvatar"
                      alt=""
                      @load="handleImgLoad"/>
                  <n-image
                      :style="{
                        width: canvasWidth + 'px',
                        height: canvasHeight + 'px'
                      }"
                      v-if="characterForm.characterAvatar && !characterForm.characterAvatar.startsWith('data:image')"
                      :src="fileFunction.getCharacterInfoImage(characterForm.characterAvatar)"
                      alt=""
                      @load="handleImgLoad"/>
                </n-space>
                <n-empty description="未上传图片" v-if="!characterForm.characterAvatar">
                  <template #extra>
                    <n-upload
                        :custom-request="customRequest"
                        :accept="'image/*'"
                    >
                      <n-button>上传图片</n-button>
                    </n-upload>
                  </template>
                </n-empty>
              </n-card>
            </n-form-item-gi>


            <n-form-item-gi :span="24" label="外网链接" path="ccRemoteUrl">
              <n-input-group>
                <n-input v-model:value="characterForm.ccRemoteUrl"> </n-input>
                <n-button @click="openPostImages"> 打开上传地址 </n-button>
              </n-input-group>

            </n-form-item-gi>

            <n-form-item-gi v-if="characterForm.styleAvatar!=null && characterForm.styleAvatar.length>0" :span="24"
                            label="参考幅度" path="styleValue">
              <n-radio-group v-model:value="characterForm.styleValue">
                <n-radio-button
                    v-for="style in styleValueOptions"
                    :value="style.value"
                    v-model:value="characterForm.styleValue"
                    :label="style.label"
                />
              </n-radio-group>
            </n-form-item-gi>

            <n-form-item-gi  v-if="characterForm.engineType==='SD'" :span="24" label=" ">
              <n-alert type="warning" style="width: 100%">
                如您需要选择Lora,请先选择SD资源!
              </n-alert>
            </n-form-item-gi>
            <n-form-item-gi v-if="characterForm.engineType==='SD'" :span="24" label="LoRA" path="characterLora">
              <n-select v-model:value="characterForm.resourceId" :options="resourceOption">
              </n-select>
              <n-input v-model:value="characterForm.characterLora" placeholder="人物使用的LoRA"
                       style="margin-left: 5px;">
              </n-input>
              <n-button :disabled="!characterForm.resourceId" type="primary" style="margin-left: 5px;"
                        @click="modelSelectorShow = true">模型选择
              </n-button>
            </n-form-item-gi>
            <n-form-item-gi :span="24" label="人物标签" path="characterLora">
              <n-select :options="characterTags" multiple v-model:value="characterForm.characterTags"></n-select>
            </n-form-item-gi>
          </n-grid>
        </n-form>
        <template #footer>
          <n-space justify="end">
            <n-button @click="addModalShow=false;getCharacterInfoList()">取消</n-button>
            <n-button type="primary" @click="submitForm" :loading="saveLoading">确定</n-button>
          </n-space>
        </template>
      </n-drawer-content>
    </n-drawer>


    <n-drawer v-model:show="modelSelectorShow" :width="promptTemplateWidth">
      <n-drawer-content title="Lora模型选择器" closable>
        <ModelSelector modelType="lora" :resourceId="characterForm.resourceId"
                       @modelSelectEvent="modelSelectEvent"></ModelSelector>
      </n-drawer-content>
    </n-drawer>

    <n-drawer v-model:show="promptTemplateShow" :width="promptTemplateWidth">
      <n-drawer-content title="提示词生成器" closable>
        <PromptTemplate code="02" @loadPromptEvent="loadPromptEvent"></PromptTemplate>
      </n-drawer-content>
    </n-drawer>

    <n-drawer v-model:show="detailDesignShow" :width="promptTemplateWidth" :close-on-esc="false">
      <n-drawer-content title="模型图片制作" :closable="true">
        <stableDiffusionPaint
            ref="stableDiffusionPaintRef"
            :defaultConfig="defaultConfig"
            from="character"
            :chosePic="chosePic"
        />
      </n-drawer-content>
    </n-drawer>


    <n-modal  v-model:show="syncModalShow" @after-leave="getCharacterInfoList" >
      <n-card
        style="width: 600px"
        title="同步进度"
        :bordered="false"
        size="huge"
        role="dialog"
        aria-modal="true"
      >
        <SyncDataSchdule v-if="syncTaskId" :taskId="syncTaskId"></SyncDataSchdule>
      </n-card>
    </n-modal>

  </div>
</template>

<script lang="ts" setup>
import {h, nextTick, onMounted, reactive, ref} from 'vue'
import {NButton, NTag, UploadCustomRequestOptions} from "naive-ui";
import Bus from '@/components/file/box/GlobalUploader/utils/bus.js'
import {storeToRefs} from "pinia";
import {useSystemStore} from "@/store/modules/useSystemStore";
import {AddSharp} from "@vicons/ionicons5";
import fileFunction from '@/libs/globalFunction/file.js'
import {resourceController} from "@/api/resource/resourceController.api"
import {characterInfoController} from "@/api/controller/characterInfo/characterInfoController"
import PromptTemplate from "@/components/prompt/promptTemplate.vue"
import ModelSelector from "@/components/paint/modelSelector/modelSelector.vue"
import {useStaticDict} from "@/dictionary/useStaticDict"
import stableDiffusionPaint from '@/views/pages/aiart/stablediffusion/index.vue'
import {ttsDict} from "@/dictionary/ttsDict";
import {setting} from "@/config/setting";
import SyncDataSchdule from "@/components/syncData/syncDataSchdule.vue";


const {client} = setting
const promptTemplateWidth = ref(0)
const {
  clientHeight,
  layoutHeaderHeight,
  darkTheme,
  tabsHeight
} = storeToRefs(useSystemStore());
const characterInfoList = ref([])
// 性别字典
const sexDict = ref<Array<any>>([
  {
    label: "男性",
    value: "男性",
  },
  {
    label: "女性",
    value: "女性"
  }
])
const formRef = ref(null)
const syncModalShow = ref(false)
const syncTaskId = ref(null)
const {ageTypeOptions} = ttsDict()
const addModalShow = ref(false)
const promptTemplateShow = ref(false)
const modelSelectorShow = ref(false)
const detailDesignShow = ref(false)
const resourceOption = ref([])
const queryForm = ref({
  tags: '',
  name: '',
  paintEngines: '',
  isOnline:'0'
})
const interrogateLoading = ref(false)
const syncLoading = ref(false)
// 设置canvas宽高
const canvasWidth = ref(300)
const canvasHeight = ref(300)

const uploadDiscordLoading = ref(false)

const formTitle = ref('新增人物信息')

const defaultConfig = ref({})

const stableDiffusionPaintRef = ref(null)

const paginationReactive = reactive({
  page: 1,
  pageSize: 10,
  pageSizes: [10, 30, 60]
})
const tableTotal = ref(0)

const onPageChange = (page: number) => {
  paginationReactive.page = page
  getCharacterInfoList()
}
const onPageSizeChange = (pageSize: number) => {
  paginationReactive.pageSize = pageSize
  getCharacterInfoList()
}

const paintEngine = ref([
  {
    label: 'Stable Diffusion',
    value: 'SD',
    checked: false
  },
  {
    label: 'MidJourney',
    value: 'MJ',
    checked: false
  },
  {
    label: 'Fooocus',
    value: 'Fooocus',
    checked: false
  }
])


const typeOptions = ref([

  {
    label: '云端',
    value: '1'
  },{
    label: '本地',
    value: '0'
  }
])
const characterTags = ref([
  {
    label: '男性',
    checked: false,
    value: '男性'
  }, {
    label: '女性',
    checked: false,
    value: '女性'
  }, {
    label: '青年',
    checked: false,
    value: '青年'
  }, {
    label: '中年',
    checked: false,
    value: '中年'
  }, {
    label: '老年',
    checked: false,
    value: '老年'
  }, {
    label: '儿童',
    checked: false,
    value: '儿童'
  }, {
    label: '古风',
    checked: false,
    value: '古风'
  },
  {
    label: '现代',
    checked: false,
    value: '现代'
  }, {
    label: '动物',
    checked: false,
    value: '动物'
  },
  {
    label: '自定义',
    checked: false,
    value: '自定义'
  }
])


const characterForm = ref({
  id: '',
  characterName: '',
  characterNickname: '',
  characterDescription: '',
  characterLora: '',
  characterPersonality: '',
  characterAge: '',
  characterGender: '',
  characterAvatar: '',
  styleAvatar: '',
  styleValue: 'default',
  characterVoiceActor: '',
  characterTag: '',
  resourceId: '',
  characterTags: [],
  characterNicknames: [],
  engineType: '',
  remoteUrl: '',
  remoteStyleUrl: '',
  ccRemoteUrl: ''
})

const resetForm = () => {
  characterForm.value = {
    id: '',
    characterName: '',
    characterNickname: '',
    characterDescription: '',
    characterLora: '',
    characterPersonality: '',
    characterAge: '',
    characterGender: '',
    characterAvatar: '',
    styleAvatar: '',
    styleValue: 'default',
    characterVoiceActor: '',
    characterTag: '',
    resourceId: '',
    characterTags: [],
    characterNicknames: [],
    remoteStyleUrl: '',
    ccRemoteUrl: ''
  }
}

const tableLoading = ref(false)
const deleteLoading = ref(false)
const saveLoading = ref(false)

const rules = {
  characterName: [
    {required: true, message: '请输入人物名称', trigger: 'submit'}
  ],
  characterDescription: [
    {required: true, message: '请输入人物描述', trigger: 'submit'}
  ],
  characterGender: [
    {required: true, message: '请选择性别', trigger: 'submit'}
  ],
  engineType: [
    {required: true, message: '请选择引擎', trigger: 'submit'}
  ],
  characterAge: [
    {required: true, message: '请选择年龄段', trigger: 'submit'}
  ],
  characterAvatar: [
    {required: true, message: '请上传人物图片', trigger: 'submit'}
  ]
}

const styleValueOptions = [
  {
    label: '默认',
    value: 'default'
  },
  {
    label: '弱化',
    value: 'weak'
  },
  {
    label: '强烈',
    value: 'strong'
  }
]

const props = defineProps({
  mode: {
    type: String,
    default: 'characterEdit'
  },
  choseCharacter: {
    type: Function,
    default: () => {
    }
  }
})

const getCharacterInfoList = () => {
  tableLoading.value = true
  const tags: any = []
  characterTags.value.forEach((tag: any) => {
    if (tag.checked) {
      tags.push(tag.value)
    }
  })
  const paintEngines: any = []
  paintEngine.value.forEach((engine: any) => {
    if (engine.checked) {
      paintEngines.push(engine.value)
    }
  })
  queryForm.value.tags = tags.join(',')
  queryForm.value.paintEngines = paintEngines.join(',')
  characterInfoController.getCharacterInfoList(queryForm.value,{
    page: paginationReactive.page,
    pageSize: paginationReactive.pageSize
  }).then((res) => {
    tableLoading.value = false
    if (res.code === 200) {
      tableTotal.value = res.data.total

      characterInfoList.value = res.data.records
      characterInfoList.value.forEach((item: any) => {
        item.characterTags = item.characterTag.split(',')
        item.characterNicknames = item.characterNickname.split(',')
      })
    }
  }).finally(() => {
    tableLoading.value = false
  })

}


const handleImgLoad = (e: any) => {
  const image = e.target;
  let image_new = new Image()
  image_new.src = image.src
  image_new.onload = function () {
    // 计算图片宽高比例
    let imgRatio = image_new.width / image_new.height
    if (image_new.width > 400
        || image_new.height > 400) {
      // 计算缩放后的宽高
      if (imgRatio > 1) {
        canvasWidth.value = 400
        canvasHeight.value = image_new.height / (image_new.width / 400)
      } else {
        // 图片比较宽
        canvasWidth.value = image_new.width / (image_new.height / 400)
        canvasHeight.value = 400
      }
    } else {
      canvasWidth.value = image_new.width
      canvasHeight.value = image_new.height
    }
  }
}


const customStyleRequest = (uploadOption: UploadCustomRequestOptions) => {
  const reader = new FileReader();
  //@ts-ignore
  reader.readAsDataURL(uploadOption.file.file);
  reader.onloadend = () => {
    let image = new Image()
    image.src = reader.result
    //@ts-ignore
    characterForm.value.styleAvatar = reader.result
  };
}


const customRequest = (uploadOption: UploadCustomRequestOptions) => {
  const reader = new FileReader();
  //@ts-ignore
  reader.readAsDataURL(uploadOption.file.file);
  reader.onloadend = () => {
    let image = new Image()
    image.src = reader.result
    //@ts-ignore
    characterForm.value.characterAvatar = reader.result
  };
}
onMounted(() => {
  getCharacterInfoList()
  getResourceInfo()
  promptTemplateWidth.value = window.innerWidth - 300
  window.addEventListener('resize', handleResize);
})

// 窗口宽度变化
const handleResize = () => {
  promptTemplateWidth.value = window.innerWidth - 300;
}


const submitForm = () => {
  formRef.value?.validate((errors) => {
    if (!errors) {
      saveLoading.value = true
      characterForm.value.characterTag = characterForm.value.characterTags.join(',')
      characterForm.value.characterNickname = characterForm.value.characterNicknames.join(',')
      if (characterForm.value.characterAvatar && characterForm.value.characterAvatar.startsWith('data:image')) {
        characterForm.value.characterAvatar = characterForm.value.characterAvatar.split(';base64,')[1]
      }
      if (characterForm.value.styleAvatar && characterForm.value.styleAvatar.startsWith('data:image')) {
        characterForm.value.styleAvatar = characterForm.value.styleAvatar.split(';base64,')[1]
      }
      characterInfoController.addCharacterInfo(characterForm.value).then((res) => {
        if (res.code === 200) {
          addModalShow.value = false
          getCharacterInfoList()
        }
      }).finally(() => {
        saveLoading.value = false
        characterForm.value.characterAvatar = "data:image/png;base64," + characterForm.value.characterAvatar
      })
    }
  })
}

/***
 * 获取绘画资源
 */
const getResourceInfo = () => {
  resourceController.getSDResource('SD').then(res => {
    if (res.code === 200) {
      res.data.forEach((item: any) => {
        // @ts-ignore
        resourceOption.value.push({
          label: item.resourceName,
          value: item.id
        })
      })
      console.log(resourceOption.value)
    }
  })
}

const deleteCharacterInfo = (row: any) => {
  window.$dialog.warning({
    title: "温馨提醒",
    content: "是否删除该人物模特",
    positiveText: "确定",
    negativeText: "取消",
    onPositiveClick: () => {
      deleteLoading.value = true
      characterInfoController.deleteCharacterInfo(row.id).then(res => {
        if (res.code === 200) {
          window.$message.success(res.msg)
          getCharacterInfoList()
        }
      }).finally(() => {
        deleteLoading.value = false
      })
    }
  })
}


const sexSelect = (key: any) => {
  characterForm.value.characterTags = []
  addTag()
}

const addTag = () => {
  if (characterForm.value.characterGender) {
    characterForm.value.characterTags.push(characterForm.value.characterGender)
  }
  if (characterForm.value.characterAge) {
    characterForm.value.characterTags.push(characterForm.value.characterAge)
  }
}

const ageSelect = (key: any) => {
  console.log(key)
  characterForm.value.characterTags = []
  addTag()
}

const modelSelectEvent = (modelObj: any) => {
  characterForm.value.characterLora = "<lora:" + modelObj.modelName + ":1>"
  modelSelectorShow.value = false
}


const loadPromptEvent = (prompt: string, negativePrompt: string) => {
  characterForm.value.characterDescription = prompt
  promptTemplateShow.value = false
}

const openSdPlugin = (characterInfo: any) => {
  defaultConfig.value = {
    "resourceId": "c602a2e2829137e0de0b0a443e4f0782",
    "defaultStyleId": "",
    "defaultPrompt": "(masterpiece:1.4, best quality),unity 8k wallpaper,ultra detailed,beautiful and aesthetic,perfect lighting,detailed background",
    "defaultNegativePrompt": "NSFW,paintings, sketches, lowres, normal quality, worst quality, low quality, cropped, dot, mole, ugly, grayscale, monochrome, duplicate, morbid, mutilated, missing fingers, extra fingers, too many fingers, fused fingers, mutated hands, bad hands, poorly drawn hands, poorly drawn face, poorly drawn eyebrows, bad anatomy, cloned face, long neck, extra legs, extra arms, missing arms missing legs, malformed limbs, deformed, simple background, bad proportions, disfigured, skin spots, skin blemishes, age spot, bad feet, error, text, extra digit, fewer digits, jpeg artifacts, signature, username, blurry, watermark, mask, logo",
    "defaultSeed": -1,
    "defaultSamplerName": "DPM++ 2M",
    "defaultBatchSize": 1,
    "defaultSteps": 20,
    "defaultWidth": 512,
    "defaultHeight": 512,
    "defaultRepaintTimes": 1,
    "defaultCfgScale": 7,
    "defaultModel": "toonyou_beta6.safetensors [e8d456c42e]",
    "defaultVae": "vae-ft-mse-840000-ema-pruned.safetensors",
    "sizeOption": "",
    "defaultClipSkip": 2,
    "defaultRestoreFaces": true,
    "defaultEnableHr": false,
    "defaultHrUpscaler": "R-ESRGAN 4x+",
    "defaultHrScale": 2,
    "defaultDenoisingStrength": 0.75,
    "defaultHrSecondPassSteps": 8,
    "defaultInterrogator": "wd14-vit-v2-git",
    "defaultRepaintModel": "img2img",
    "defaultResizeMode": "0",
    "defaultControlNet": {
      "input_image": "",
      "mask": "",
      "module": "tile_colorfix+sharp",
      "model": "control_v11f1e_sd15_tile_fp16 [3b860298]",
      "weight": 1,
      "resize_mode": 1,
      "lowvram": false,
      "processor_res": 0,
      "threshold_a": 8,
      "threshold_b": 0.35,
      "guidance": 1,
      "guidance_start": 0,
      "guidance_end": 1,
      "control_mode": 2,
      "pixel_perfect": true,
      "preProcessor": "Tile/Blur",
      "is_enable": false
    }
  };
  detailDesignShow.value = true
  characterForm.value = characterInfo
  nextTick(() => {
    let sex = 'male'
    if (characterInfo && characterInfo?.characterGender === '女性') {
      sex = 'female'
    }
    const prompt = 'solo,white background,simple background,' + sex + ',' + characterInfo.characterDescription + ',' + characterInfo.characterLora
    stableDiffusionPaintRef.value.loadPrompt(prompt, null);
  })
}

const chosePic = (userFileId: string) => {
  // 更新
  characterForm.value.characterAvatar = userFileId
  const avatarDto = {
    id: characterForm.value.id,
    userFileId: userFileId
  }
  characterInfoController.saveAvatar(avatarDto).then((res) => {
    if (res.code === 200) {
      window.$message.success(res.msg)
      getCharacterInfoList()
    }
  }).finally(() => {
    detailDesignShow.value = false
  })

}

const editForm = (characterInfo: any) => {
  formTitle.value = '编辑人物信息'
  characterForm.value = characterInfo
  addModalShow.value = true
}

const uploadToDiscord = (id: string) => {
  uploadDiscordLoading.value = true
  characterInfoController.uploadToDiscord(id).then(res => {
    if (res.code === 200) {
      window.$message.success(res.msg)
      getCharacterInfoList()
    }
  }).finally(() => {
    uploadDiscordLoading.value = false
  })
}


const interrogateImage = () => {
  interrogateLoading.value = true
  const interrogateData = {...characterForm.value}
  console.log(interrogateData)
  const data = {
    imageData: interrogateData.characterAvatar.split(';base64,')[1]
  }
  characterInfoController.interrogateImage(data).then(res => {
    if (res.code === 200) {
      characterForm.value.characterDescription = res.data
    }
  }).finally(() => {
    interrogateLoading.value = false
  })
}

const syncData = () =>{
  syncLoading.value = true
  characterInfoController.syncData().then(res => {
    if (res.code === 200){
      syncTaskId.value = res.data
      syncModalShow.value = true
    }
  }).finally(() => {
    syncLoading.value = false
  })
}

const uploadToTuchuang = (characterId:string) => {
  characterInfoController.uploadToTuchuang(characterId).then(res => {
    if (res.code === 200){
      window.$message.success(res.msg)
    }
  })
}

const openPostImages = ()=>{
  const url = "https://postimages.org/"
  const newWindow = window.open(url, '_blank');
  if (newWindow) {
    // 网页成功打开
  } else {
    // 网页打开被阻止
    alert('请允许弹出窗口');
  }
}
</script>

